package com.dhecp.project.common.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.dhecp.project.flowable.domain.SysProcessInstance;
import com.dhecp.project.flowable.service.ActProcessTaskService;

import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.dhecp.common.core.controller.BaseController;
import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.common.utils.IpUtils;
import com.dhecp.common.utils.MessageUtils;
import com.dhecp.common.utils.RandomValueUtils;
import com.dhecp.common.utils.TypeUtils;
import com.dhecp.core.constant.ModuleTableToEntity;
import com.dhecp.core.layui.GridColumnsPropertyModel;
import com.dhecp.framework.util.ShiroUtils;
import com.dhecp.framework.web.service.BaseInfoSimpleService;
import com.dhecp.project.base.domain.BaseInfo;
import com.dhecp.project.common.dealdata.InfoMapData;
import com.dhecp.project.common.service.ButtonStateService;
import com.dhecp.project.system.domain.SysDictionaryForPageField;
import com.dhecp.project.system.domain.SysDictionaryRelationForModule;
import com.dhecp.project.system.domain.SysFilesInfo;
import com.dhecp.project.system.domain.SysRuleSet;
import com.dhecp.project.system.domain.SysSetting;
import com.dhecp.project.system.service.SysDictionaryForFieldService;
import com.dhecp.project.system.service.SysDictionaryRelationForModuleService;
import com.dhecp.project.system.service.SysFilesInfoService;
import com.dhecp.project.system.service.SysRuleSetService;

/**
 * 业务单据基础控制层
 * @author DH-Xxj
 * @version 2019年11月20日
 */
@Controller
public class BaseModuleController extends BaseController {
    
    @Autowired
    private SysDictionaryForFieldService dictionaryForFieldService;
    
    
    @Autowired
    private GridColumnsPropertyModel gridColumnsPropertyModel;

	@Autowired
    private SysDictionaryRelationForModuleService dictionaryRelationForModuleService;
	
	@Autowired
	private SysFilesInfoService sysFilesInfoService;
    
    @Autowired
    private ActProcessTaskService actProcessTaskService;
	
	@Autowired
	private InfoMapData infoMapData;
	
	@Autowired
	private BaseInfoSimpleService baseInfoSimpleService;
	
	@Autowired
	private ButtonStateService buttonStateService;
	
	@Autowired
    private SysRuleSetService ruleSetService;
	
    /**
     * 打开查询列表页
     * @param params
     * @return ModelAndView
     * @author DH-Xxj
     */
    public Map<String, Object> openListPage(@RequestParam Map<String, Object> params){
    	Map<String, Object> mv = new HashMap<String, Object>();
    	Integer toolBarWidth = 0;
    	if (params.get("toolBarWidth") == null || params.get("toolBarWidth") == ""){
    		params.put("toolBarWidth", toolBarWidth);
    	}
    	
        AjaxResult ajaxResult = new AjaxResult();
        Map<String, Object> gridColumns = new HashMap<String, Object>();
        Map<String, Object> buttonState = new HashMap<String, Object>();
        try{
        	params.put("getFieldAttributesSystemType", "mobile");//web：网页端；mobile：手机端
        	gridColumns = gridColumnsPropertyModel.queryGridColumnsPropertyModel(params);
        	buttonState = checkButtonState(params);	//按钮状态：（可用：enable，禁用：disable，隐藏：hidden）
        }
        catch(Exception e){
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        
        mv.put("moduleTable", params.get("moduleTable").toString());
        mv.put("ajaxResult", ajaxResult);
        mv.put("gridColumns", gridColumns);
        mv.put("buttonState", TypeUtils.mapToJson(buttonState));	//按钮状态：（可用：enable，禁用：disable，隐藏：hidden）
		return mv;
    }
    
    /**
     * 返回gridColumns对象
     * @param params 默认只传moduleTable
     * @return gridColumns
     * @author DH-lwl
     */
    @PostMapping("/common/gridColumns")
    @ResponseBody
    public AjaxResult backGridColumns(@RequestParam Map<String, Object> params){
    	if (params.get("moduleTable") == null || params.get("moduleTable") == ""){
    		return AjaxResult.error("请提供必要参数：moduleTable。");
    	}
		if (params.get("getFieldAttributesType") == null || params.get("getFieldAttributesType") == ""){
    		params.put("getFieldAttributesType","page");//默认显示全部字段——形如查询列表
    	}
    	Map<String, Object> gridColumns = new HashMap<String, Object>();
    	params.put("moduleTable", params.get("moduleTable"));
    	params.put("entity", ModuleTableToEntity.queryEntityByModuleTable(params.get("moduleTable").toString()).get("entity"));
		params.put("getFieldAttributesSystemType", "mobile");//web：网页端；mobile：手机端
    	gridColumns = gridColumnsPropertyModel.queryGridColumnsPropertyModel(params);
    	return AjaxResult.success(MessageUtils.message("module.success.issuccess"), TypeUtils.mapToJson(gridColumns));
    }
    
    /**
     * 打开制单页面
     * @param params
     * @return ModelAndView ajaxResult：提示消息，fieldRequiredList：必填字段，fieldsList：显示的表头，fieldsHiddenList：隐藏的表头，gridColumns：明细网格格。
     * @author DH-Xxj
     */
    @SuppressWarnings("unchecked")
	public Map<String, Object> openEditPage(@RequestParam Map<String, Object> params){
    	Map<String, Object> mv = new HashMap<String, Object>();
    	String moduleTableY = "";
    	if (params.get("toolBarWidth") == null || params.get("toolBarWidth") == ""){	//默认不生成操作区宽度
    		params.put("toolBarWidth", 0);
    	}
    	if (params.get("moduleTable") != null){	//保存原始moduleTable，审批环节如果需要打开审批专用页面需要临时修改moduleTable值，生成页面后变回原值
    		moduleTableY = params.get("moduleTable").toString();
    	}
        Boolean isEdit=false;//默认不是生成强制可编辑页面
    	String nid = params.get("nid").toString();
        String moduleUrl = params.get("moduleUrl").toString();
        String prefix = params.get("prefix").toString();
        String aUser = "";
        String bUser = "";
        String activeFlow = "";
        String actFuncKey = "";		//审批环节功能KEY
        String actFormPage = "";	//审批环节跳转页面
        Boolean actFuncIsEdit = false;	//审批环节是否可编辑
        AjaxResult ajaxResult = new AjaxResult();
        List<SysDictionaryForPageField> dicFieldsList = new ArrayList<SysDictionaryForPageField>(); //字段字典
        Object importFields = null;
        List<Object> fieldsList = new ArrayList<Object>(); 					//生成表头控件的字段和属性
        List<Object> fieldsHiddenList = new ArrayList<Object>(); 			//生成表头隐藏的字段和属性
        List<Object> bFieldsList = new ArrayList<Object>(); 				//生成底部控件的字段和属性
        List<Object> bFieldsHiddenList = new ArrayList<Object>(); 			//生成底部隐藏的字段和属性
        List<Object> fieldsStaticList = new ArrayList<Object>(); 			//生成静态控件的字段和属性
        List<Map<String, Object>> fieldsListTemp = new ArrayList<Map<String, Object>>(); //临时存储区，用于存放需要放到最后生成的控件，如：备注等大文本控件
        List<Map<String, Object>> fieldsListTempLable = new ArrayList<Map<String, Object>>(); //临时存储区，用于存放需要放到最后生成的标题/注解（t_lable）控件
    	List<String> decimalList = new ArrayList<String>();					//数值类型的字段
        List<String> fieldRequiredList = new ArrayList<String>(); 			//必填字段
        Map<String, Object> gridColumns = new HashMap<String, Object>();	//生成的表格
        Map<String, Object> decimalMap = new HashMap<String, Object>();		//数值类型小数位数
        Map<String, Object> buttonState = new HashMap<String, Object>();	//按钮状态：（可用：enable，禁用：disable，隐藏：hidden）
        Map<String, Object> headData = (Map<String, Object>) params.get("headData");	//表头的业务数据

        if (headData.get("bigData") == null || headData.get("bigData") == ""){
        	//大数据处理专用单号，用于单据数据量过大，需要分批传输的情况，单据新增时随机生成，需存储于单据中。
        	headData.put("bigData", RandomValueUtils.getGUID());
        }
        
        if (headData.get("aUser") != null){aUser = headData.get("aUser").toString();}
        if (headData.get("bUser") != null){bUser = headData.get("bUser").toString();}
        if (headData.get("activeFlow") != null){activeFlow = headData.get("activeFlow").toString();}
        params.put("activeFlow", activeFlow);

		Map<String, Object> infoMap  = new HashMap<String, Object>();
		infoMap.put("procInstId", headData.get("procInstId").toString());
		int checkProcessTask = 0;
		checkProcessTask = checkProcessTask(infoMap);

		if (checkProcessTask != 0){
	        //查询当前流程环节，判断是打开制单页面还是其它审批专用页面
	        SysProcessInstance processInstance = actProcessTaskService.querySysProcessInstanceByTableDataId(nid);
	        if (processInstance != null){
	        	if (processInstance.getActFuncKey() != null){actFuncKey = processInstance.getActFuncKey();}
	        	if (processInstance.getActFormPage() != null){
	        		actFormPage = processInstance.getActFormPage();
	        		if (!"".equals(actFormPage)){
		        		prefix = moduleUrl + "/" + actFormPage; //如果流程环节中配置了审批环节跳转页面，则打开配置的页面
	        		}
	        	}
	        	actFuncIsEdit = processInstance.getActFuncIsEdit();
	        }
		}
        
        List<SysDictionaryRelationForModule> relationlist = new ArrayList<SysDictionaryRelationForModule>(); //调入功能列表
        Object relationObj = new Object();
        List<SysFilesInfo> reportlist = new ArrayList<SysFilesInfo>(); //打印报表列表
        Object reportObj = new Object();
        
        SysSetting sysSetting = ShiroUtils.getSystemSet();					//系统设置信息
        
        try{
        	buttonState = checkButtonState(params);	//按钮状态：（可用：enable，禁用：disable，隐藏：hidden）
	    	if ("disable".equals(buttonState.get("filedelete").toString()) && (aUser.equals(ShiroUtils.getUserId()) || bUser.equals(ShiroUtils.getUserId()))){
	    		buttonState.put("filedelete", "enable");	//当前登录用户为制单人或代理人时允许删除附件
	    	}
        	Boolean enableEdit = checkModuleEditPermissions(activeFlow, aUser, bUser);
            if (params.get("isEdit") != null && params.get("isEdit").equals("1")){//判断是否强制生成可编辑页面，无论是否流转或制单人
            	isEdit=true;
        	}
        	if (enableEdit || isEdit){
            	params.put("readOnly", false);	//生成可编辑的网格	
        	}else{
            	params.put("readOnly", !actFuncIsEdit);	//actFuncIsEdit为false（不可编辑）时，生成只读的网格	
            	buttonState = buttonStateToDisable(buttonState,actFuncIsEdit,null);	//单据不可编辑状态下，把指定按钮改为不可用
        	}
        	
        	if (!"".equals(actFuncKey)){ //审批环节功能KEY不为空，需要使用专属审批页面字典
        		params.put("moduleTable", moduleTableY + "_" + actFuncKey);
        	}
        	params.put("getFieldAttributesType", "pageingrid"); 			//制单页面表格
        	params.put("getFieldAttributesSystemType", "mobile");			//web：网页端；mobile：手机端
        	gridColumns = gridColumnsPropertyModel.queryGridColumnsPropertyModel(params);
        	params.put("getFieldAttributesType", "pagenotingrid"); 			//制单页面非表格（头部、底部）
        	dicFieldsList = dictionaryForFieldService.queryFieldAttributesList(params);
        	
        	params.put("moduleTable", moduleTableY);	//还原到原始moduleTable
        	importFields = dictionaryForFieldService.queryFieldFrontImport(params); //导入模板
        	relationlist = dictionaryRelationForModuleService.queryDictionaryRelationForModuleByRModuleTable(params.get("moduleTable").toString()); //调入功能列表
        	
        	if (relationlist.isEmpty() || relationlist.size() == 0){
        		relationObj = null;
        	}else{
        		Map<String, Object> relationMap = new LinkedHashMap<String, Object>();
        		for (SysDictionaryRelationForModule relation : relationlist){
            		relationMap.put(relation.getRelationName().toString(), relation.getGuid().toString());        			
        		}
        		relationObj = TypeUtils.mapToJson(relationMap);
        	}
        	

    		Map <String, Object> reportParams = new HashMap<String, Object>();
    		reportParams.put("fileMark", params.get("moduleTable").toString());
        	reportlist = sysFilesInfoService.queryReportForModule(reportParams); //打印报表列表
        	if (reportlist.isEmpty() || reportlist.size() == 0){
        		reportObj = null;
        	}else{
        		Map<String, Object> reportMap = new LinkedHashMap<String, Object>();
        		
        		for (SysFilesInfo report : reportlist){
        			reportMap.put(report.getFilePath().toString(), report.getFileName().toString());        			
        		}
        		reportObj = TypeUtils.mapToJson(reportMap);
        	}

            Integer decimalForPrice = sysSetting.getDecimalForPrice();		//价格小数位数
            Integer decimalForSum = sysSetting.getDecimalForSum();			//金额小数位数
            Integer decimalForNumber = sysSetting.getDecimalForNumber();	//数量小数位数
            Integer decimalForPercent = sysSetting.getDecimalForPercent();	//百分比小数位数
            
            if (dicFieldsList.isEmpty()){
                ajaxResult = AjaxResult.error("未获取到字段属性，请开发人员调试。");
                buttonState = buttonStateToDisable(buttonState,false,"errorpage");	//异常情况，把指定按钮改为不可用
            }else{
                ajaxResult = AjaxResult.success("数据获取成功。");
                String activeFlowName="准备制单";
                if (!"".equals(nid) && !"0".equals(nid)){
                	try{
                        activeFlowName = actProcessTaskService.queryActivitiImplNameByNid(nid);
                	}catch(Exception e){
                		activeFlowName = "未知环节";
                	}
                }
                if ("".equals(activeFlowName) || activeFlowName == null || "end".equals(activeFlow)){
                	if ("end".equals(activeFlow)){
                		activeFlowName = "结束";
                	}else{
                    	activeFlowName = "未知环节";
                	}
                }else if ("未知环节".equals(activeFlowName) && "end".equals(activeFlow)){
            		activeFlowName = "结束";
            	}
                
            	for (SysDictionaryForPageField dicFields : dicFieldsList){
            		Map<String, Object> fieldsListMap = TypeUtils.entityToMap(dicFields);
            		if (headData.get(fieldsListMap.get("fields")) == null && !"t_lable".equals(fieldsListMap.get("fieldFrontType").toString())){
                    	buttonState = buttonStateToDisable(buttonState,false,"errorpage");	//页面异常，把指定按钮改为不可用
            			throw new Exception("表头缺少字段【" + fieldsListMap.get("fields").toString() + "】，可能的原因：大小写问题、实体缺少该字段。");
            		}
            		if ("activeflowname".equals(fieldsListMap.get("fields").toString().toLowerCase())){
                		fieldsListMap.put("fieldContent", activeFlowName);
            		}else{
            			if ("t_date".equals(dicFields.getFieldFrontType()) && headData.get(fieldsListMap.get("fields")).toString().length() > 9){
                    		fieldsListMap.put("fieldContent", headData.get(fieldsListMap.get("fields")).toString().substring(0, 10));
            			}else{
                    		fieldsListMap.put("fieldContent", headData.get(fieldsListMap.get("fields")));
            			}
            		}
            		
            		//如果有下拉控件，则根据配置获取对应下拉待选内容
            		List<BaseInfo> dropdownList = new ArrayList<BaseInfo>();
            		String fieldFrontType = dicFields.getFieldFrontType();
            		String fieldSearchType = dicFields.getFieldSearchType();
            		String fieldFrontSave = dicFields.getFieldFrontSave();
            		String fieldFrontShow = dicFields.getFieldFrontShow();
            		if (fieldFrontType != null && fieldFrontType.toLowerCase().startsWith("t_dropdown")){
            			if (fieldSearchType != null && !"".equals(fieldSearchType)){
            				if (fieldFrontSave == null || "".equals(fieldFrontSave)){
            					fieldFrontSave = "vid";
            				}
            				if (fieldFrontShow == null || "".equals(fieldFrontShow)){
            					fieldFrontShow = "vname";
            				}
            				dropdownList = baseInfoSimpleService.getDropdownData(fieldSearchType,fieldFrontSave,fieldFrontShow);
            			}
            		}
            		fieldsListMap.put("dropdownList", dropdownList);
            		
            		if (fieldsListMap.get("fieldFrontType") == null){
            			fieldsListMap.put("fieldFrontType", "t_text");
            		}
            		
            		if ("t_textarea".equals(fieldsListMap.get("fieldFrontType").toString())){ //大文本控件放入临时存储区
            			fieldsListTemp.add(fieldsListMap);
            		}else if ("t_lable".equals(fieldsListMap.get("fieldFrontType").toString()) && (Integer)fieldsListMap.get("fieldFrontTopOrder") > 10000){
            			fieldsListTempLable.add(fieldsListMap);
            		}else if ((Integer)fieldsListMap.get("fieldFrontTop") == 1){ //显示的表头
                		fieldsList.add(TypeUtils.mapToJson(fieldsListMap));
            		}else if ((Integer)fieldsListMap.get("fieldFrontTop") == 2){ //隐藏的表头
            			fieldsHiddenList.add(TypeUtils.mapToJson(fieldsListMap));
            		}else if ((Integer)fieldsListMap.get("fieldFrontTop") == 5){ //显示的底部
            			bFieldsList.add(TypeUtils.mapToJson(fieldsListMap));
            		}else if ((Integer)fieldsListMap.get("fieldFrontTop") == 6){ //隐藏的底部
            			bFieldsHiddenList.add(TypeUtils.mapToJson(fieldsListMap));
            		}else if ((Integer)fieldsListMap.get("fieldFrontTop") == 8){ //静态的字段
            			fieldsStaticList.add(TypeUtils.mapToJson(fieldsListMap));
            		}
            		
            		if (dicFields.getFieldFrontRequired() != null && dicFields.getFieldFrontRequired()){
            			//必填字段数组
            			fieldRequiredList.add(dicFields.getFields());
            		}
                   	
                	if ("int".equals(dicFields.getFieldType()) || dicFields.getFieldType().indexOf("decimal") != -1){
                		String field = dicFields.getFields().toString();
                		decimalList.add(field); //添加数值类型字段
                		if ("t_price".equals(dicFields.getFieldFrontTemplet().toString())){
                			decimalMap.put(field, decimalForPrice);
                		}else if ("t_sum".equals(dicFields.getFieldFrontTemplet().toString())){
                			decimalMap.put(field, decimalForSum);
                		}else if ("t_number".equals(dicFields.getFieldFrontTemplet().toString())){
                			decimalMap.put(field, decimalForNumber);
                		}else if ("t_percent".equals(dicFields.getFieldFrontTemplet().toString()) || "p_percent".equals(dicFields.getFieldFrontTemplet().toString())){
                			decimalMap.put(field, decimalForPercent);
                		}else if ("t_appoint1".equals(dicFields.getFieldFrontTemplet().toString()) || "p_appoint1".equals(dicFields.getFieldFrontTemplet().toString())){
                			decimalMap.put(field, 1);
                		}else if ("t_appoint2".equals(dicFields.getFieldFrontTemplet().toString()) || "p_appoint2".equals(dicFields.getFieldFrontTemplet().toString())){
                			decimalMap.put(field, 2);
                		}else if ("t_appoint3".equals(dicFields.getFieldFrontTemplet().toString()) || "p_appoint3".equals(dicFields.getFieldFrontTemplet().toString())){
                			decimalMap.put(field, 3);
                		}else if ("t_appoint4".equals(dicFields.getFieldFrontTemplet().toString()) || "p_appoint4".equals(dicFields.getFieldFrontTemplet().toString())){
                			decimalMap.put(field, 4);
                		}else if ("t_appoint5".equals(dicFields.getFieldFrontTemplet().toString()) || "p_appoint5".equals(dicFields.getFieldFrontTemplet().toString())){
                			decimalMap.put(field, 5);
                		}else if ("t_appoint6".equals(dicFields.getFieldFrontTemplet().toString()) || "p_appoint6".equals(dicFields.getFieldFrontTemplet().toString())){
                			decimalMap.put(field, 6);
                		}else{
                			decimalMap.put(field, 0);
                		}
                	}
            	}
            	
            	if (!fieldsListTemp.isEmpty() && fieldsListTemp.size() > 0){
            		for (Map<String, Object> fieldsMap : fieldsListTemp){ //大文本控件追加到数组末尾
            			if ((Integer)fieldsMap.get("fieldFrontTop") == 1){ //显示的表头
                    		fieldsList.add(TypeUtils.mapToJson(fieldsMap));
                		}else if ((Integer)fieldsMap.get("fieldFrontTop") == 2){ //隐藏的表头
                			fieldsHiddenList.add(TypeUtils.mapToJson(fieldsMap));
                		}else if ((Integer)fieldsMap.get("fieldFrontTop") == 5){ //显示的底部
                			bFieldsList.add(TypeUtils.mapToJson(fieldsMap));
                		}else if ((Integer)fieldsMap.get("fieldFrontTop") == 6){ //隐藏的底部
                			bFieldsHiddenList.add(TypeUtils.mapToJson(fieldsMap));
                		}else if ((Integer)fieldsMap.get("fieldFrontTop") == 8){ //静态的字段
                			fieldsStaticList.add(TypeUtils.mapToJson(fieldsMap));
                		}
            		}
            	}
            	
            	if (!fieldsListTempLable.isEmpty() && fieldsListTempLable.size() > 0){
            		for (Map<String, Object> fieldsMap : fieldsListTempLable){ //表头排序大于10000的标题/注解追加到数组末尾
            			if ((Integer)fieldsMap.get("fieldFrontTop") == 1){ //显示的表头
                    		fieldsList.add(TypeUtils.mapToJson(fieldsMap));
                		}else if ((Integer)fieldsMap.get("fieldFrontTop") == 2){ //隐藏的表头
                			fieldsHiddenList.add(TypeUtils.mapToJson(fieldsMap));
                		}else if ((Integer)fieldsMap.get("fieldFrontTop") == 5){ //显示的底部
                			bFieldsList.add(TypeUtils.mapToJson(fieldsMap));
                		}else if ((Integer)fieldsMap.get("fieldFrontTop") == 6){ //隐藏的底部
                			bFieldsHiddenList.add(TypeUtils.mapToJson(fieldsMap));
                		}else if ((Integer)fieldsMap.get("fieldFrontTop") == 8){ //静态的字段
                			fieldsStaticList.add(TypeUtils.mapToJson(fieldsMap));
                		}
            		}
            	}
            	
            }
        }
        catch(Exception e){
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }

        Boolean isLeadCheck = true;
        if (checkProcessTask==0)isLeadCheck = false;
        //模块规则设置对象
        List<SysRuleSet> ruleList = new ArrayList<SysRuleSet>();
        Map<String, Object> ruleMap = new HashMap<String, Object>();
        ruleList = ruleSetService.querySysRuleSetForPage(params.get("moduleTable").toString());
        if (!ruleList.isEmpty() && ruleList.size() > 0){
        	for(SysRuleSet SysRuleInfo : ruleList){
        		ruleMap.put(SysRuleInfo.getVrule(), SysRuleInfo);
        	}
        }

        mv.put("moduleTable", moduleTableY);	//功能唯一标识
        mv.put("moduleUrl", moduleUrl);		//页面上级路径
        mv.put("ajaxResult", ajaxResult);					//提示消息
        mv.put("importFields",importFields);				//导入字段模板
        mv.put("decimalList",decimalList);				//数值类型字段
        mv.put("decimalObj", TypeUtils.mapToJson(decimalMap));//数值类型小数位数
        mv.put("fieldRequiredList", fieldRequiredList);	//必填字段
        mv.put("fieldsList", fieldsList);					//显示的表头
        mv.put("fieldsHiddenList", fieldsHiddenList);		//隐藏的表头
        mv.put("bFieldsList", bFieldsList);				//显示的底部
        mv.put("bFieldsHiddenList", bFieldsHiddenList);	//隐藏的底部
        mv.put("fieldsStaticList", fieldsStaticList);		//静态字段
        mv.put("gridColumns", gridColumns);				//明细网格
        mv.put("relationObj", relationObj);				//调入功能列表
        mv.put("buttonState", TypeUtils.mapToJson(buttonState));	//按钮状态：（可用：enable，禁用：disable，隐藏：hidden）
        mv.put("reportObj", reportObj);					//打印模板列表
        mv.put("isLeadCheck", isLeadCheck);				//是否直属上级审核
        mv.put("checkProcessTask", checkProcessTask);		//是否有审核权限
        mv.put("isEdit", isEdit);							//是否强制可编辑
        mv.put("ruleObj", ruleMap);						//模块规则设置
        mv.put("isShow", params.get("isShow") != null?true:false);			//传递页面参数，控制表头按钮及页脚显示
    	
    	return mv;
    }
    
    /**
     * 打开单条数据详情页
     * @param params
     * @return
     * @author DH-Xxj
     */
    @SuppressWarnings("unchecked")
	public Map<String, Object> openDetailPage(@RequestParam Map<String, Object> params){
    	Map<String, Object> mv = new HashMap<String, Object>();;
        AjaxResult ajaxResult = new AjaxResult();
        List<SysDictionaryForPageField> dicFieldsList = new ArrayList<SysDictionaryForPageField>(); //字段字典
		List<Object> fieldsList = new ArrayList<Object>();	
        Map<String, Object> detailMap = (Map<String, Object>) params.get("detailMap");

    	dicFieldsList = dictionaryForFieldService.queryFieldAttributesList(params);
    	
        if (dicFieldsList.isEmpty()){
            ajaxResult = AjaxResult.error("未获取到字段属性。");
            mv.put("ajaxResult", ajaxResult);
            return mv;
        }else{
        	for (SysDictionaryForPageField dicFields : dicFieldsList) {
        		if (!dicFields.getFieldFrontHidden() && !"check".equals(dicFields.getFieldType().toLowerCase())){
            		Map<String, Object> fieldsListMap = TypeUtils.entityToMap(dicFields);
            		String fields = fieldsListMap.get("fields").toString();
            		fieldsListMap.put("fieldContent", detailMap.get(fields));
            		fieldsList.add(TypeUtils.mapToJson(fieldsListMap));
        		}
        	}
        }
    	        
		mv.put("fieldsList", fieldsList);
    	return mv;
    }

    /**
     * 流转、退回、驳回
     * @param fType 必要参数：审核类型（flow_go：流转，flow_back：退回，flow_reject：驳回
	 * @param infoMap 必要参数：非网格字段（包括所有显示和隐藏的字段），json格式字符串
     * @return AjaxResult
     * @author DH-Xxj
     */
	@SuppressWarnings("unchecked")
	@PostMapping("/commonflow")
	@ResponseBody
    public AjaxResult openFlowPage(@RequestParam Map<String, Object> params){
    	String flowUrl = "";
    	if (params.get("infoMap") == null || params.get("infoMap") ==""){
    		return AjaxResult.error("请提供参数：非网格字段【infoMap】");
    	}else{
    		//强转为不区分大小写的CaseInsensitiveMap
    		Map<String, Object> infoMap = new CaseInsensitiveMap(infoMapData.infoMapDeal(params.get("infoMap").toString(), params.get("moduleTable").toString()));
        	if (infoMap.get("activeFlow") == null || infoMap.get("activeFlow") == ""){
        		return AjaxResult.error("请提供参数：下一环节流程状态【activeFlow】");
        	}else if (infoMap.get("createTime") == null || infoMap.get("createTime") == ""){
        		return AjaxResult.error("请提供参数：创建日期【createTime】");
        	}else if (infoMap.get("nid") == null || infoMap.get("nid") == ""){
        		return AjaxResult.error("请提供参数：单据编码【nid】");
        	}else if ("0".equals(infoMap.get("nid").toString())){
        		return AjaxResult.error(MessageUtils.message("module.warn.unsave"));
        	}else if (params.get("fType") == null || params.get("fType") == ""){
        		return AjaxResult.error("请提供参数：审核类型（flow_go：流转，flow_back：退回，flow_reject：驳回）");
        	}else if ("end".equals(infoMap.get("activeFlow").toString().toLowerCase())){
        		if ("flow_go".equals(params.get("fType").toString())){
            		return AjaxResult.warn(MessageUtils.message("module.warn.isflowfinished"));
        		}else if ("flow_back".equals(params.get("fType").toString())){ //重置退回
					if (infoMap.get("enableChange") == null || (Boolean)infoMap.get("enableChange") == false){
						return AjaxResult.warn(infoMap.get("enableChangemsg").toString());
					}else{
						String nid = infoMap.get("nid").toString();
						//判断当前人是否是最后一级审批人，不是返回提示
						if(actProcessTaskService.isCanProcessEndBack(nid, ShiroUtils.getMandatorId()) == false){
							return AjaxResult.error(MessageUtils.message("flowable.task.error.unneeddeal"));
						}
						flowUrl = "/flowable/task/taskRestBack?nid=" + infoMap.get("nid").toString() + "&jumpUrl=" + params.get("prefix").toString() + "/flowbackpost";
						return AjaxResult.success("成功", flowUrl);
					}
				}else{
            		return AjaxResult.warn(MessageUtils.message("module.warn.isflowfinished.disableback"));
        		}
        	}else if (checkProcessTask(infoMap) == 0 && !("flow_reject".equals(params.get("fType").toString()) && ShiroUtils.getMandatorLevel() > 5)){
        		return AjaxResult.error(MessageUtils.message("flowable.task.error.unneeddeal"));
        	}else if ("flow_go".equals(params.get("fType").toString())){ //流转
        		flowUrl = "/flowable/task/taskPass?nid=" + infoMap.get("nid").toString() + "&jumpUrl=" + params.get("prefix").toString() + "/flowgopost";
        		return AjaxResult.success("成功", flowUrl);	
    		}else if ("flow_back".equals(params.get("fType").toString())){ //退回
    			if (infoMap.get("enableChange") == null || (Boolean)infoMap.get("enableChange") == false){
            		return AjaxResult.warn(infoMap.get("enableChangemsg").toString());
    			}else if ("flowzd".equals(infoMap.get("activeFlow").toString().toLowerCase())){
            		return AjaxResult.warn(MessageUtils.message("module.warn.isflowzd"));
    			}else{
        			flowUrl = "/flowable/task/taskBack?nid=" + infoMap.get("nid").toString() + "&jumpUrl=" + params.get("prefix").toString() + "/flowbackpost";
        			return AjaxResult.success("成功", flowUrl);	
    			}
    		}else if ("flow_reject".equals(params.get("fType").toString())){ //驳回
    			if (infoMap.get("enableChange") == null || (Boolean)infoMap.get("enableChange") == false){
            		return AjaxResult.warn(infoMap.get("enableChangemsg").toString());
    			}else if ("flowzd".equals(infoMap.get("activeFlow").toString().toLowerCase())){
            		return AjaxResult.warn(MessageUtils.message("module.warn.isflowzd"));
    			}else{
        			flowUrl = "/flowable/task/taskReject?nid=" + infoMap.get("nid").toString() + "&jumpUrl=" + params.get("prefix").toString() + "/flowbackpost";
        			return AjaxResult.success("成功", flowUrl);	
    			}
    		}else{
        		return AjaxResult.error("审核类型(fType)有误，有效值为：流转（flow_go），退回（flow_back），驳回（flow_reject）。");
    		}  
    	}
    }

    /**
     * 返回流转页链接
     * @param fType 必要参数：审核类型（flow_go：流转，flow_back：退回）
	 * @param infoMap 必要参数：非网格字段（包括所有显示和隐藏的字段），json格式字符串
     * @return
     * @author DH-Xxj
     */
    public String flowPageUrl(@RequestParam Map<String, Object> params){
    	String flowUrl = "";
    	String sErrorUrl = "/flowable/startflowchecked/error?msg=";
    	String sWarnUrl = "/flowable/startflowchecked/warn?msg=";
    	if (params.get("infoMap") == null || params.get("infoMap") ==""){
    		try {
				flowUrl = sErrorUrl + URLEncoder.encode("请提供参数：非网格字段【infoMap】","UTF-8");
			} catch (UnsupportedEncodingException e) {
				flowUrl = sErrorUrl + "lack_infoMap";
			}
    	}else{
    		Map<String, Object> infoMap = infoMapData.infoMapDeal(params.get("infoMap").toString(), params.get("moduleTable").toString());
        	if (infoMap.get("activeFlow") == null || infoMap.get("activeFlow") == ""){
        		try {
    				flowUrl = sErrorUrl + URLEncoder.encode("请提供参数：下一环节流程状态【activeFlow】","UTF-8");
    			} catch (UnsupportedEncodingException e) {
    				flowUrl = sErrorUrl + "lack_activeFlow";
    			}
        	}else if (infoMap.get("createTime") == null || infoMap.get("createTime") == ""){
        		try {
    				flowUrl = sErrorUrl + URLEncoder.encode("请提供参数：创建日期【createTime】","UTF-8");
    			} catch (UnsupportedEncodingException e) {
    				flowUrl = sErrorUrl + "lack_createTime";
    			}
        	}else if (infoMap.get("nid") == null || infoMap.get("nid") == ""){
        		try {
    				flowUrl = sErrorUrl + URLEncoder.encode("请提供参数：单据编码【nid】","UTF-8");
    			} catch (UnsupportedEncodingException e) {
    				flowUrl = sErrorUrl + "lack_nid";
    			}
        	}else if ("0".equals(infoMap.get("nid").toString())){
        		try {
    				flowUrl = sErrorUrl + URLEncoder.encode(MessageUtils.message("module.warn.unsave"),"UTF-8");
    			} catch (UnsupportedEncodingException e) {
    				flowUrl = sErrorUrl + "module.warn.unsave";
    			}
        	}else if (params.get("fType") == null || params.get("fType") == ""){
        		try {
    				flowUrl = sErrorUrl + URLEncoder.encode("请提供参数：审核类型（flow_go：流转，flow_back：退回）","UTF-8");
    			} catch (UnsupportedEncodingException e) {
    				flowUrl = sErrorUrl + "lack_fType";
    			}
        	}else if (checkProcessTask(infoMap) == 0){
        		try {
    				flowUrl = sErrorUrl + URLEncoder.encode(MessageUtils.message("flowable.task.error.unneeddeal"),"UTF-8");
    			} catch (UnsupportedEncodingException e) {
    				flowUrl = sErrorUrl + "flowable.task.error.unneeddeal";
    			}
        	}else if ("flow_go".equals(params.get("fType").toString())){ //流转
        		if ("end".equals(infoMap.get("activeFlow").toString().toLowerCase())){
            		try {
        				flowUrl = sWarnUrl + URLEncoder.encode(MessageUtils.message("module.warn.isflowfinished"),"UTF-8");
        			} catch (UnsupportedEncodingException e) {
        				flowUrl = sWarnUrl + "module.warn.isflowfinished";
        			}
        		}else{
            		flowUrl = "/flowable/task/taskPass?nid=" + infoMap.get("nid").toString() + "&jumpUrl=" + params.get("prefix").toString() + "/flowgopost";
        		}
    		}else if ("flow_back".equals(params.get("fType").toString())){ //退回
    			if (infoMap.get("enableChange") == null || (Boolean)infoMap.get("enableChange") == false){
            		try {
        				flowUrl = sWarnUrl + URLEncoder.encode(infoMap.get("enableChangemsg").toString(),"UTF-8");
        			} catch (UnsupportedEncodingException e) {
        				flowUrl = sWarnUrl + "disableChange";
        			}
    			}else if ("flowzd".equals(infoMap.get("activeFlow").toString().toLowerCase())){
            		try {
        				flowUrl = sWarnUrl + URLEncoder.encode(MessageUtils.message("module.warn.isflowzd"),"UTF-8");
        			} catch (UnsupportedEncodingException e) {
        				flowUrl = sWarnUrl + "module.warn.isflowzd";
        			}
    			}else{
        			flowUrl = "/flowable/task/taskBack?nid=" + infoMap.get("nid").toString() + "&jumpUrl=" + params.get("prefix").toString() + "/flowbackpost";
    			}
    		}else{
        		try {
    				flowUrl = sErrorUrl + URLEncoder.encode("审核类型(fType)有误，有效值为：流转（flow_go），退回（flow_back）","UTF-8");
    			} catch (UnsupportedEncodingException e) {
    				flowUrl = sErrorUrl + "error_fType";
    			}
    		}  
    	}
		
    	return flowUrl;
    }
    
    /**
     * 流程验证错误消息
     * @param msg 提示信息
     * @return AjaxResult
     * @author DH-Xxj
     */
    @GetMapping("/flowable/startflowchecked/error")
    @ResponseBody
    public AjaxResult startFlowCheckedError(@RequestParam Map<String, Object> params){
    	String msg = params.get("msg").toString();
        return AjaxResult.error(msg);
    }
    
    /**
     * 流程验证提醒消息
     * @param  msg 提示信息
     * @return AjaxResult
     * @author DH-Xxj
     */
    @GetMapping("/flowable/startflowchecked/warn")
    @ResponseBody
    public AjaxResult startFlowCheckedWarn(@RequestParam Map<String, Object> params){
    	String msg = params.get("msg").toString();
        return AjaxResult.warn(msg);
    }
    
    /**
     * 验证单据是否需要当前用户审核
     * @param infoMap
     * @return int (0：无需当前用户审核，非0：需要当前用户审核)
     * @author DH-Xxj
     */
    public int checkProcessTask(@RequestParam Map<String, Object> infoMap){
    	String proInsId = "proInsId";
    	String userId = ShiroUtils.getMandatorId();
    	if (infoMap.get("procInstId") != null && infoMap.get("procInstId") != ""){
    		proInsId = infoMap.get("procInstId").toString();
    	}
		return actProcessTaskService.queryUserCurrentInstanceRunTaskCount(proInsId, userId);
    }
    
    /**
     * 验证单据是否允许修改
     * @param activeFlow
     * @return
     * @author DH-Xxj
     */
    public Boolean checkModuleEditPermissions(String activeFlow,String aUser, String bUser){
    	Boolean perm = false;
    	String loginUser = ShiroUtils.getUserId();
    	if ((loginUser.equals(aUser) || loginUser.equals(bUser)) && ("".equals(activeFlow) || "flowzd".equals(activeFlow.toString().toLowerCase()))){
    		perm = true;
    	}
    	return perm;
    }

    /**
     * 检查按钮权限
     * @param moduleTable 必要参数：功能唯一标识
     * @return Map - buttonState
     * @author DH-Xxj
     */
    public Map<String, Object> checkButtonState(Map<String, Object> params){
    	Map<String, Object> buttonState = new HashMap<String, Object>();	//按钮状态：（可用：enable，禁用：disable，隐藏：hidden）
    	Map<String, Object> buttonMap = new HashMap<String, Object>();
    	if (params.get("moduleTableForButton") == null || params.get("moduleTableForButton") == ""){
    		if (params.get("moduleTable") == null || params.get("moduleTable") == ""){
        		buttonMap.put("moduleTable", "moduleTable");
    		}else{
        		buttonMap.put("moduleTable", params.get("moduleTable"));
    		}
    	}else{
    		buttonMap.put("moduleTable", params.get("moduleTableForButton"));
    	}
    	
    	if (params.get("activeFlow") == null || params.get("activeFlow") == ""){
    		buttonMap.put("activeFlow", "");
    	}else{
    		buttonMap.put("activeFlow", params.get("activeFlow"));
    	}
    	
    	buttonState = buttonStateService.getButtonStateObjectForUser(buttonMap);
    	return buttonState;
    }
    
    /**
     * 单据不可编辑状态下，把指定按钮改为不可用
     * @param buttonState
     * @return buttonState
     * @author DH-Xxj
     */
    public Map<String, Object> buttonStateToDisable(Map<String, Object> buttonState, Boolean actFuncIsEdit, String type){
    	for (String field : buttonState.keySet()){
    		if (field.indexOf("addbtn") > -1 				//单据不可编辑状态下，不允许新增明细
	    			|| field.indexOf("copybtn") > -1 		//单据不可编辑状态下，不允许复制明细
	    			|| field.indexOf("importbtn") > -1 		//单据不可编辑状态下，不允许导入明细
	    			|| field.indexOf("deletebatch") > -1	//单据不可编辑状态下，不允许删除明细
	    			|| field.indexOf("tp-delete") > -1 		//单据不可编辑状态下，不允许删除单据
	    			|| field.indexOf("tp-callin") > -1 		//单据不可编辑状态下，不允许调入明细
	    			|| (field.indexOf("tp-save") > -1 && !actFuncIsEdit)	//单据不可编辑状态下，不允许保存明细
	    			|| "errorpage".equals(type)	//单据因异常而不可编辑状态下，所有按钮不可用
    			){
    	    	if ("enable".equals(buttonState.get(field).toString())){
    	    		buttonState.put(field, "disable");	//单据不可编辑状态下，按钮不可用
    	    	}
    		}
    	}
    	
    	/*
    	if ("enable".equals(buttonState.get("addbtn").toString())){
    		buttonState.put("addbtn", "disable");	//单据不可编辑状态下，不允许新增明细
    	}
    	if ("enable".equals(buttonState.get("importbtn").toString())){
    		buttonState.put("importbtn", "disable");	//单据不可编辑状态下，不允许导入明细
    	}
    	if ("enable".equals(buttonState.get("deletebatch").toString())){
    		buttonState.put("deletebatch", "disable");	//单据不可编辑状态下，不允许删除明细
    	}
    	if ("enable".equals(buttonState.get("tp-delete").toString())){
    		buttonState.put("tp-delete", "disable");	//单据不可编辑状态下，不允许删除单据
    	}
    	if ("enable".equals(buttonState.get("tp-callin").toString())){
    		buttonState.put("tp-callin", "disable");	//单据不可编辑状态下，不允许调入明细
    	}
    	if ("enable".equals(buttonState.get("tp-save").toString())){
    		buttonState.put("tp-save", "disable");	//单据不可编辑状态下，不允许保存单据
    	}
    	*/
    	return buttonState;
    }

}
